using System;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using MefContrib.Models.Provider.Definitions.Fluent;
using NUnit.Framework;

namespace MefContrib.Models.Provider.Tests.Definitions
{
    [TestFixture]
    public class FluentDefinitionProviderTests : DefinitionProviderTests
    {
        private readonly CompositionContainer _container;

        public FluentDefinitionProviderTests()
        {
            var provider = new FluentDefinitionProvider();
            var catalog = new DefinitionProviderPartCatalog<FluentDefinitionProvider>(provider);
            var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var aggregateCatalog = new AggregateCatalog(catalog, assemblyCatalog);
            var container = new CompositionContainer(aggregateCatalog);

            _container = container;

            provider
                .Export<DefaultContractExport>()
                .Export<DefaultContractImport>().WithContract<DefaultContractImport>()
                .Export<Many1>(t => t).WithContract<IMany>()
                .Export<Many2>(t => t).WithContract<IMany>()
                .Export<Foo1>(t => t).WithContract<IFoo>()
                .Export<Foo2>(t => t).WithContract<IFoo>("Foo2")
                .Export<Bar1>(t => t).WithContract<Bar1>()
                .Export<Bar2>(t => t).WithContract<Bar2>()
                .Import<DefaultContractImport>(t => t.Foo)
                .Import<Bar1>(t => t.Foo)
                .Import<Bar1>(t => t.MefComponent).WithContract<IMefComponent>()

                .Export<PropretyExporterUsingDefaultContract>(t => t.Value)
                .Export<PropretImporterUsingDefaultContract>()
                .Import<PropretImporterUsingDefaultContract>(t => t.Value)

                .Export<PropretyExporterUsingNamedContract>(t => t.Value).WithContract("Value")
                .Export<PropretImporterUsingNamedContract>()
                .Import<PropretImporterUsingNamedContract>(t => t.Value).WithContract("Value")

                .Export<FieldExporterUsingDefaultContract>(t => t._stringField)
                .Export<FieldImporterUsingDefaultContract>()
                .Import<FieldImporterUsingDefaultContract>(t => t._stringField2)

                .Export<FieldExporterUsingNamedContract>(t => t._stringField).WithContract("FldValue")
                .Export<FieldImporterUsingNamedContract>()
                .Import<FieldImporterUsingNamedContract>(t => t._stringField2).WithContract("FldValue")

                .Export<MethodExporterUsingDefaultContract>(t => t.Bar(default(int), default(double)))
                .Export<MethodImporterUsingDefaultContract>()
                .Import<MethodImporterUsingDefaultContract>(t => t.BarMethod)

                .Export<MethodExporterUsingNamedContract>(t => t.Bar(default(int), default(double))).WithContract("method_bar")
                .Export<MethodImporterUsingNamedContract>()
                .Import<MethodImporterUsingNamedContract>(t => t.BarMethod).WithContract("method_bar");
        }

        protected override CompositionContainer Container
        {
            get { return _container; }
        }
    }
}